/* nixonFTP
 * FTP client version 0.1
 * Copyright (C) 2010 NIXON Development Corporation.
 * All rights reserved.
 * http://members.shaw.ca/nixon.com
*/

package nixonftp.ui;

import nixonftp.list.NXTable;
import nixonftp.*;
import nixonftp.list.NXList;
import nixonftp.list.NXListRenderer;
import nixonftp.list.NXListAdapter;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyListener;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import javax.accessibility.AccessibleContext;
import javax.swing.*;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.Timer;
import nixonftp.list.NXDefaultListModel;

public class NXFtpBrowserPanel extends JPanel implements KeyListener, ActionListener {

	private ArrayList<NXList> listBoxes = new ArrayList<NXList>();
	private ArrayList<JScrollPane> scrollers = new ArrayList<JScrollPane>();
	public JPanel accountPanel;
	public JPanel listingPanel;
	public JPanel crumbPanel;
	private JPanel browserPanel;
	public JScrollPane browserScroll;
	public NXTable table;
	public FtpCredentialInputField txtHost;
	public FtpCredentialInputField txtUser;
	public FtpPasswordInputField txtPassword;
	public JRadioButton radFtp;
	public JRadioButton radSftp;
	private JPanel protocolPanel;
	public JButton btnConnect;
	public JMenu originalMenu;
	public ArrayList<NXTraverseMenu> locations = new ArrayList<NXTraverseMenu>();
	private JViewport parentView;
	private boolean local;
	public boolean init = true;

	private double start; //for animation
	private int end;
	private final Timer timer;

	private NXFilter[] filters;
	public boolean listing = false;
	public FtpCredentialInputField txtInitialDir;
	public JCheckBox chkPreload;

	public NXFtpBrowserPanel(boolean account, boolean local) {
		super();
		this.local = local;
		setLayout(new BoxLayout(this, BoxLayout.X_AXIS));

		browserPanel = new JPanel();
		browserPanel.setBackground(new Color(255, 255, 255));
		browserPanel.setLayout(new BoxLayout(browserPanel, BoxLayout.X_AXIS));
		browserScroll = new NXScrollPane(browserPanel);
		add(browserScroll);

		listingPanel = new JPanel();
		table = new NXTable(local);
		listingPanel.setLayout(new BoxLayout(listingPanel, BoxLayout.Y_AXIS));
		crumbPanel = new JPanel();
		crumbPanel.add(new NXCrumb("/", ""));
		listingPanel.add(crumbPanel);
		listingPanel.add(new JScrollPane(table));
		listingPanel.setVisible(false);
		add(listingPanel);

		if (account) {
			browserScroll.setVisible(false);
			listingPanel.setVisible(false);
			accountPanel = new JPanel(new GridBagLayout());
			accountPanel.setBorder(BorderFactory.createEmptyBorder(16,16,16,16));

			GridBagConstraints c = new GridBagConstraints();
			accountPanel.setBackground(new Color(255, 255, 255));

			ClassLoader cldr = this.getClass().getClassLoader();
			ImageIcon serverIcon = new ImageIcon(cldr.getResource("icons/pre_server.png"));

			JLabel lblConnect = new JLabel("Connect");
			lblConnect.setIcon(serverIcon);
			lblConnect.setIconTextGap(10);
			lblConnect.setFont(new Font("Verdana", Font.BOLD, 18));
			c.gridwidth = 2;
			c.fill = GridBagConstraints.HORIZONTAL;
			c.gridx = 0;
			c.gridy = 0;
			c.insets = new Insets(3, 5, 3, 5);
			accountPanel.add(lblConnect, c);

			JLabel lblProtocol = new JLabel("Protocol:", SwingConstants.RIGHT);
			c.gridwidth = 1;
			c.gridx = 0;
			c.gridy = 1;
			accountPanel.add(lblProtocol, c);

			protocolPanel = new JPanel();
			protocolPanel.setOpaque(false);
			c.gridx = 1;
			c.gridy = 1;
			accountPanel.add(protocolPanel, c);

			ButtonGroup protocolGroup = new ButtonGroup();
			radFtp = new JRadioButton("FTP", true);
			protocolGroup.add(radFtp);
			setAccessible(radFtp, "FTP protocol", "Standard File Transfer Protocol", true);
			protocolPanel.add(radFtp, c);

			radSftp = new JRadioButton("Secure Shell FTP");
			protocolGroup.add(radSftp);
			setAccessible(radFtp, "Secure FTP protocol", "SSH File Transfer Protocol", true);
			protocolPanel.add(radSftp, c);

			JLabel lblHost = new JLabel("Server address:", SwingConstants.RIGHT);
			c.gridx = 0;
			c.gridy = 2;
			accountPanel.add(lblHost, c);

			txtHost = new FtpCredentialInputField(15);
			txtHost.addKeyListener(this);
			txtHost.setToolTipText("<html>Server domain name or IP address<br><font color='#666666'>Example: </font><b>ftp.domain.com</b></html>");
			c.gridx = 1;
			accountPanel.add(txtHost, c);

			JLabel lblUser = new JLabel("User name:", SwingConstants.RIGHT);
			c.gridx = 0;
			c.gridy = 3;
			accountPanel.add(lblUser, c);

			txtUser = new FtpCredentialInputField(15);
			txtUser.addKeyListener(this);
			txtUser.setEnabled(false);
			setAccessible(txtUser, "Username", "User name (leave blank if anonymous)", true);
			c.gridx = 1;
			accountPanel.add(txtUser, c);

			JLabel lblPassword = new JLabel("Password:", SwingConstants.RIGHT);
			c.gridx = 0;
			c.gridy = 4;
			accountPanel.add(lblPassword, c);

			txtPassword = new FtpPasswordInputField(15);
			setAccessible(txtPassword, "Password", "Password (leave blank if anonymous)", true);
			txtPassword.setEnabled(false);
			c.gridx = 1;
			accountPanel.add(txtPassword, c);
			
			//initial directory
			JLabel lblInitialDir = new JLabel("Initial directory:", SwingConstants.RIGHT);
			c.gridx = 0;
			c.gridy = 5;
			accountPanel.add(lblInitialDir, c);

			txtInitialDir = new FtpCredentialInputField(15);
			setAccessible(txtInitialDir, "Initial Directory", "Directory to change to after logging in", true);
			c.gridx = 1;
			accountPanel.add(txtInitialDir, c);
			
			chkPreload = new JCheckBox("Preload");
			c.gridy = 6;
			accountPanel.add(chkPreload, c);
			chkPreload.setSelected(true);

			btnConnect = new JButton("Connect");
			setAccessible(btnConnect, "Connect", "Connect to the server", true);
			btnConnect.setEnabled(false);
			c.gridx = 1;
			c.gridy = 7;
			accountPanel.add(btnConnect, c);

			Font f = lblHost.getFont();
			Font newF = f.deriveFont(f.getStyle() ^ Font.BOLD);
			lblHost.setFont(newF);
			lblProtocol.setFont(newF);
			lblUser.setFont(newF);
			lblPassword.setFont(newF);
			Color grey = new Color(96,96,96);
			lblHost.setForeground(grey);
			lblUser.setForeground(grey);
			lblPassword.setForeground(grey);
			lblInitialDir.setForeground(grey);
			chkPreload.setForeground(grey);
			add(accountPanel);
		}
		//addList();
		timer = new Timer(0, this);
		filters = new NXFilter[1];
		filters[0] = new NXFilter(NXFilter.DATE, NXFilter.COLOR, NXFilter.WITHIN, 1, NXFilter.DAYS);
		filters[0].setColor(new Color(204,255,204));
	}

	private void setAccessible(JComponent c, String name, String desc, boolean toolTip) {
		AccessibleContext ac = c.getAccessibleContext();
		ac.setAccessibleName(name);
		ac.setAccessibleDescription(desc);
		if (toolTip) c.setToolTipText(desc);
	}

	public void showAccountPanel(boolean b) {
		accountPanel.setVisible(b);
		validateAccountPanel();
		if (listing) {
			listingPanel.setVisible(!b);
		} else {
			browserScroll.setVisible(!b);
		}
	}

	public boolean toggleAccountPanel() {
		boolean b = !accountPanel.isVisible();
		if (!init) {
			showAccountPanel(b);
		}
		return b;
	}

	public void validateAccountPanel() {
		boolean b = !txtHost.getText().equals("");
		txtUser.setEnabled(b);
		txtPassword.setEnabled(!txtUser.getText().equals(""));
		btnConnect.setEnabled(b);
	}

	public void setInit(boolean b) {
		init = b;
	}

	public String[] getValues() {
		String[] s = new String[3];
		s[0] = txtHost.getText();
		s[1] = txtUser.getText();
		s[2] = String.copyValueOf(txtPassword.getPassword());
		return s;
	}

	public void addList() {
		int size = listBoxes.size();
		NXList newList = new NXList(size, local);
		NXScrollPane listScrollPane = new NXScrollPane(newList, 200);
		newList.setCellRenderer(new NXListRenderer());
		scrollers.add(listScrollPane);
		newList.setFilters(filters);
		listBoxes.add(newList);
		browserPanel.add(listScrollPane);
		revalidate();
		updateUI();
		newList.requestFocusInWindow();
		if (parentView == null) parentView = (JViewport) browserPanel.getParent();
		timer.start();
	}

	public void addItemsToList(NXListAdapter list, NXObjectIndex[] items) {
		NXDefaultListModel dm = new NXDefaultListModel();
		ListModel m = list.getAdapterModel();
		NXObjectIndex oi;
		boolean[] alreadyExists = new boolean[items.length];
		for (int x = 0; x < m.getSize(); x++) {
			oi = (NXObjectIndex) m.getElementAt(x);
			for (int y = 0; y < items.length; y++) {
				if (oi.name.equals(items[y].name)) alreadyExists[y] = true;
			}
			dm.addElement(oi);
		}

		for (int z = 0; z < items.length; z++) {
			if (!alreadyExists[z]) dm.addElement(items[z]);
		}
		
		list.setModel(dm);
	}

	public void remoteItemsFromList(NXListAdapter list, NXObjectIndex[] items) {
		NXDefaultListModel dm = new NXDefaultListModel();
		ListModel m = list.getAdapterModel();
		NXObjectIndex oi;
		for (int x = 0; x < m.getSize(); x++) {
			oi = (NXObjectIndex) m.getElementAt(x);
			for (int y = 0; y < items.length; y++) {
				if (!oi.name.equals(items[y].name)) dm.addElement(oi);
			}
		}
		list.setModel(dm);
	}

	public void keyTyped(KeyEvent e) {
	}

	public void keyPressed(KeyEvent e) {
	}

	public void keyReleased(KeyEvent e) {
		//throw new UnsupportedOperationException("Not supported yet.");
		JTextField c = (JTextField) e.getComponent();

		if (c.equals(txtHost)) {
			txtUser.setEnabled(!txtHost.getText().equals(""));
			txtPassword.setEnabled(!txtUser.getText().equals(""));
			btnConnect.setEnabled(!c.getText().equals(""));
		} else if (c.equals(txtUser)) {
			txtPassword.setEnabled(!c.getText().equals(""));
		}
	}

	public void actionPerformed(ActionEvent e) {
		start = parentView.getViewPosition().x + 10;
		end = browserPanel.getWidth() - parentView.getWidth();
		if (start < end) {
			parentView.setViewPosition(new Point((int) start, 0));
		} else {
			parentView.setViewPosition(new Point(end, 0));
			timer.stop();
		}
	}

	public void removeList(int index) {
		int size = listBoxes.size();
		if (index >= size) {
			return;
		}
		if (index == -1) index = size - 1;
		for (int x = size; x > index; x--) {
			NXList list = listBoxes.get(index);
			list.setVisible(false);
			browserPanel.remove(list);
			browserPanel.remove(scrollers.get(index));
			listBoxes.remove(index);
			scrollers.remove(index);
		}
		revalidate();
		updateUI();
	}

	public NXFilter[] getFilters() {
		return filters;
	}
	
	public void setFilters(NXFilter[] filters) {
		for (int x = 0; x < listBoxes.size(); x++) {
			listBoxes.get(x).setFilters(filters);
		}
		this.filters = filters;
	}

	public NXList getListBoxes(int index) {
		if (index == -1) {
			index = listBoxes.size() - 1;
		}
		return listBoxes.get(index);
	}

	public NXListAdapter getListIfShown(String dir) {
		dir = dir.replace("\\", "/");
		String cmp;
		if (listing) {
			cmp = table.getDirectory().replace("\\", "/");
			if (cmp.equals(dir)) {
				return table;
			}
		} else {
			if (dir.equals("/")) {
				return listBoxes.get(0);
			}
			NXList l;
			for (int x = 0; x < listBoxes.size(); x++) {
				l = listBoxes.get(x);
				cmp = l.getDirectory().replace("\\", "/");
				if (cmp.equals(dir)) {
					return l;
				}
			}
		}
		return null;
	}
}
